package org.rslai.socket.testtool.config;

import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;

import javax.xml.parsers.ParserConfigurationException;

import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

public class LoadConfig {

	static Logger logger = Logger.getLogger(LoadConfig.class);
	
	/**
	 * 构造函数
	 * @param configFileName 初始配置文件名（"Config.xml"），以后的所有配置均在此配置文件中配置
	 */
	public LoadConfig(String configFileName) {
		logger.warn("==================================================");

		Document doc = loadFromXML(configFileName);

		if (doc != null) {
			loadConfKeyValue( getNodeList(doc, "ConfKeyValue") );
			loadConfTable( getNodeList(doc, "ConfTable") );
		}

		logger.warn("==================================================");
	}

	/**
	 * 装载所有Key Value 的形式配置信息
	 * @param list xml文件名列表
	 * @throws IOException 
	 * @throws SAXException 
	 * @throws ParserConfigurationException 
	 */
	private void loadConfKeyValue(LinkedList<String> list) {
		Iterator<String> it = list.iterator();

		while (it.hasNext()) {
			loadKeyValue(it.next()); // 装载一个xml文件中的key value配置
		}
	}
	
	/**
	 * 装载一个xml文件中的key value配置
	 * @param xmlFileName xml文件名
	 */
	private void loadKeyValue(String xmlFileName) {
		Document doc = loadFromXML(xmlFileName);

		if (doc != null) {
			Element rootElement = doc.getDocumentElement();
			
			NodeList elements = rootElement.getElementsByTagName("Conf");
			for (int i=0; i<elements.getLength(); i++) {
				Element element = (Element)elements.item(i);
				
				org.rslai.socket.testtool.config.Data.addKeyValue(element.getAttribute("key"), element.getAttribute("value"), element.getAttribute("desc"));
			}
		}
	}
	/**
	 * 装载所有表的形式配置信息
	 * @param list xml文件名列表
	 */
	private void loadConfTable(LinkedList<String> list) {
		Iterator<String> it = list.iterator();

		while (it.hasNext()) {
			String fileName = it.next();

			// 将完整的路径+文件名分解为路径和文件名
			String directory = "";
			String csvName = "";
			int i = fileName.lastIndexOf('/');
			if (i != -1) {
				directory = fileName.substring(0, i);
				String csvFileName = fileName.substring(i+1);

				int j = csvFileName.lastIndexOf('.');
				if (j != -1) {
					csvName = csvFileName.substring(0, j);
				}
			}

			loadTable(this.getClass().getResource("/").getPath()+directory, csvName); // 根据指定目录和文件名装载一个表的形式配置信息
		}
	}

	/**
	 * 根据指定目录和文件名装载一个表的形式配置信息
	 * @param directory 目录
	 * @param fileName 文件名，不含 .cvs
	 */
	private void loadTable(String directory, String fileName) {
		ReadCsv readCsv = new ReadCsv();
		HashMap<String, HashMap<String, String>> result = readCsv.getData(directory, fileName);

		org.rslai.socket.testtool.config.Data.addTable(fileName, result);
	}

	/**
	 * 得到某个主节点下的所有FileName字节点
	 * @param doc xml Document
	 * @param nodeName 主节点名
	 * @return
	 */
	private LinkedList<String> getNodeList(Document doc, String nodeName) {
		LinkedList<String> tmpList = new LinkedList<String>();

		Element rootElement = doc.getDocumentElement();

		NodeList keyValueElements = rootElement.getElementsByTagName(nodeName); // 先取到主节点的内容
		for (int i=0; i<keyValueElements.getLength(); i++) {
			Element keyValueElement = (Element)keyValueElements.item(i);
			NodeList fileNameElements = keyValueElement.getElementsByTagName("FileName"); // 取得主节点下所有 FileName 字节点
			for (int j=0; j<fileNameElements.getLength(); j++) {
				Element fileNameElement=(Element)fileNameElements.item(j);
				tmpList.add(fileNameElement.getTextContent());
			}
		}
		return tmpList;
	}


	/**
	 * 根据指定xml文件名返回xml Document
	 * @param xmlFileName xml文件名
	 * @return
	 */
	private Document loadFromXML(String xmlFileName) {
		try {
			LoadXML loadXML = new LoadXML();
			Document doc = loadXML.loadFromXML(this.getClass().getResource("/").getPath() + xmlFileName);
			
			return doc;			
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

}
